package sundial;

// From A Beginning Programmer's Guide to Java
// at http://beginwithjava.blogspot.com/

// Used in the article 'A Most Basic Graphics Application'
// at http://beginwithjava.blogspot.com/2008/07/most-basic-graphics-app.html
// Referenced in the article 'Drawing Lines'
// at http://beginwithjava.blogspot.com/2008/07/in-most-basic-graphics-app-we-had.html

// This program demonstrates a program to do graphics that is as simple
// as possible in Java. It throws aside good coding practices for the sake
// of just being _simple_. If you just want a simple plotting program,
// this may do it for you.
// Or, better yet, it'll help you understand how to do graphics in Java
// so you can go on to write your own programs with better code.
// For more information see the original article, and the other Java
// graphics and GUI articles at the blog.
// by Mark Graybill, July 2008

// Import the basic graphics classes.
import java.awt.*;
import javax.swing.*;
import java.awt.geom.Ellipse2D;

/**
 * This class draws the hour lines on the base of the sundial.  The outer frame is fixed while
 * the hour lines may vary depending on location.
 * 
 * modified by
 * @author Takanori Shiotsu
 * @author Reyn Matsumoto
 *
 */
@SuppressWarnings("serial")
public class BasicPanel extends JPanel{
	
	private int maxHeight = 500;
	private int minHeight = 100;
	private int minWidth = 100;
	private int maxWidth = 500;
	
	private double width = (maxWidth - minWidth);
	private double height = (maxHeight - minHeight);
	
	private int centerX = (int) Math.round(width/2) + minWidth;
	
	private SundialCompute calculations;
	
	//amount of space between clock and edges
	private int borderSp = 90;
	
    // Create a constructor method
    public BasicPanel(SundialCompute computations, JFrame drawing){
        super();
        
        calculations = computations;

        drawing.setContentPane(this);          
    }

     public void paintComponent(Graphics g){
    	//edge cases
    	if ((getLatitude() == 0) || (getLatitude() == 90))
    	{
    		Graphics2D g2 = (Graphics2D) g;
    		
    		g2.draw(new Ellipse2D.Double(60,60,480,480));
    		g2.draw(new Ellipse2D.Double(5,5,590,590));
    		
    		g2.draw(new Ellipse2D.Double(287, 287, 26, 26));
    		
    		//draw lines
    		g.drawLine(300,60,300,540);//vertical
    		
    		//12 AM
    		g.drawLine(286,55,286,10); //1
    		g.drawLine(290,10,294,10); //2
    		g.drawLine(294,10,294,33);
    		g.drawLine(294,33,290,33);
    		g.drawLine(290,33,290,55);
    		g.drawLine(290,55,294,55);
    		
    		g.drawLine(306,55,306,10);//A
    		g.drawLine(306,10,310,10);
    		g.drawLine(310,10,310,55);
    		g.drawLine(310,33,306,33);
    		
    		g.drawLine(314,55,314,10);//M
    		g.drawLine(314,10,318,10);
    		g.drawLine(318,10,318,55);
    		g.drawLine(316,10,316,33);
    		
    		//12 PM
    		g.drawLine(286,545,286,590); //1
    		g.drawLine(290,545,294,545); //2
    		g.drawLine(294,545,294,568);
    		g.drawLine(294,568,290,568);
    		g.drawLine(290,568,290,590);
    		g.drawLine(290,590,294,590);
    		
    		g.drawLine(306,590,306,545);//P
    		g.drawLine(306,545,310,545);
    		g.drawLine(310,545,310,568);
    		g.drawLine(310,568,306,568);
    		
    		g.drawLine(314,590,314,545);//M
    		g.drawLine(314,545,318,545);
    		g.drawLine(318,545,318,590);
    		g.drawLine(316,545,316,568);
    		
    		g.drawLine(60,300,540,300);//horizontal
    		
    		//6 AM
    		g.drawLine(545,278,545,322);//6
    		g.drawLine(545,300,549,300);
    		g.drawLine(545,278,549,278);
    		g.drawLine(545,322,549,322);
    		g.drawLine(549,322,549,300);
    		
    		g.drawLine(561,278,561,322);//A
    		g.drawLine(561,278,565,278);
    		g.drawLine(565,278,565,322);
    		g.drawLine(561,300,565,300);
    		
    		g.drawLine(569,278,573,278);//M
    		g.drawLine(569,278,569,322);
    		g.drawLine(573,278,573,322);
    		g.drawLine(571,278,571,300);
    		
    		//6 PM
    		g.drawLine(27,278,27,322);//6
    		g.drawLine(27,300,31,300);
    		g.drawLine(27,278,31,278);
    		g.drawLine(27,322,31,322);
    		g.drawLine(31,322,31,300);
    		
    		g.drawLine(43,278,43,322);//P
    		g.drawLine(43,278,47,278);
    		g.drawLine(47,278,47,300);
    		g.drawLine(43,300,47,300);
    		
    		g.drawLine(51,278,55,278);//M
    		g.drawLine(51,278,51,322);
    		g.drawLine(55,278,55,322);
    		g.drawLine(53,278,53,300);
    		
    		g.drawLine(68,238,532,362);//15
    		g.drawLine(92,180,508,420);//30
    		g.drawLine(130,130,470,470);//45
    		g.drawLine(180,92,420,508);//60
    		g.drawLine(238,68,362,532);//75
    		
    		g.drawLine(238,532,362,68);//105
    		g.drawLine(420,92,180,508);//120
    		g.drawLine(470,130,130,470);//135
    		g.drawLine(508,180,92,420);//150
    		g.drawLine(532,238,68,362);//165
    		
    	}
    	 
    	
    	//all lines should be indented one more in - do later
    	else
    	{
    		
    		boolean DLS = daylightsavings();

    		// Boarder (90 space between inner clock and edge)
    		g.drawLine(minWidth,maxHeight,(minWidth - borderSp),maxHeight); //botLeft line

    		//AM
    		g.drawLine((minWidth - borderSp) + 3, maxHeight - 3, (minWidth - borderSp) + 3, maxHeight - 13); //A
    		g.drawLine((minWidth - borderSp) + 3, maxHeight - 13, (minWidth - borderSp) + 8, maxHeight - 13);
    		g.drawLine((minWidth - borderSp) + 8, maxHeight - 13, (minWidth - borderSp) + 8, maxHeight - 3);
    		g.drawLine((minWidth - borderSp) + 3, maxHeight - 8, (minWidth - borderSp) + 8, maxHeight - 8);

    		g.drawLine((minWidth - borderSp) + 10, maxHeight - 3, (minWidth - borderSp) + 10, maxHeight - 13);//M
    		g.drawLine((minWidth - borderSp) + 10, maxHeight - 13, (minWidth - borderSp) + 16, maxHeight - 13);
    		g.drawLine((minWidth - borderSp) + 16, maxHeight - 13, (minWidth - borderSp) + 16, maxHeight - 3);
    		g.drawLine((minWidth - borderSp) + 13, maxHeight - 13, (minWidth - borderSp) + 13, maxHeight - 3);



    		g.drawLine((minWidth - borderSp),maxHeight,(minWidth - borderSp),(minHeight - borderSp));//left line
    		g.drawLine((minWidth - borderSp),(minHeight - borderSp),(maxWidth + borderSp),(minHeight - borderSp)); //top line
    		g.drawLine((maxWidth + borderSp),(minHeight - borderSp),(maxWidth + borderSp),maxHeight);//right line

    		g.drawLine((maxWidth + borderSp),maxHeight,maxWidth,maxHeight);//botRight line

    		//PM
    		g.drawLine((maxWidth + borderSp) - 16, maxHeight - 3, (maxWidth + borderSp) - 16, maxHeight - 13); //P
    		g.drawLine((maxWidth + borderSp) - 16, maxHeight - 13, (maxWidth + borderSp) - 11, maxHeight - 13);
    		g.drawLine((maxWidth + borderSp) - 11, maxHeight - 13, (maxWidth + borderSp) - 11, maxHeight - 8);
    		g.drawLine((maxWidth + borderSp) - 11, maxHeight - 8, (maxWidth + borderSp) - 16, maxHeight - 8);

    		g.drawLine((maxWidth + borderSp) - 9, maxHeight - 3, (maxWidth + borderSp) - 9, maxHeight - 13);//M
    		g.drawLine((maxWidth + borderSp) - 9, maxHeight - 13, (maxWidth + borderSp) - 3, maxHeight - 13);
    		g.drawLine((maxWidth + borderSp) - 3, maxHeight - 13, (maxWidth + borderSp) - 3, maxHeight - 3);
    		g.drawLine((maxWidth + borderSp) - 6, maxHeight - 13, (maxWidth + borderSp) - 6, maxHeight - 3);

    		// Box for sundial
    		g.drawLine(minWidth,minHeight,minWidth,maxHeight);
    		g.drawLine(minWidth,maxHeight,maxWidth,maxHeight);
    		g.drawLine(maxWidth,maxHeight,maxWidth,minHeight);
    		g.drawLine(maxWidth,minHeight,minWidth,minHeight);

    		//////////////////////////////////////////////////////////////////////////////////


    		//hour lines, checks DLS for labeling numbers
    		int currHRLeft;
    		double drawDegree;
    		double yCoor;
    		double xCoor;

    		//line number
    		int hrLineCounter = 0;

    		//toCoordinate[0] is x coordinate to draw line to
    		//toCoordinate[1] is y coordinate to draw line to
    		int[] coordinateLeft;
    		int[] coordinateRight;
    		coordinateLeft = new int[2];
    		coordinateRight = new int[2];

    		coordinateLeft[0] = 0;
    		coordinateLeft[1] = 0;

    		coordinateRight[0] = 0;
    		coordinateRight[1] = 0;

    		if (DLS)
    		{
    			currHRLeft = 7;

    			if (Math.round(getDegreeAngle(currHRLeft)) == 0)
    			{
    				//left 7
    				g.drawLine(minWidth - 8, maxHeight - 13, minWidth - 3, maxHeight - 13);
    				g.drawLine(minWidth - 3, maxHeight - 13, minWidth - 6, maxHeight - 3);
    				g.drawLine(minWidth - 8, maxHeight - 13, minWidth - 8, maxHeight - 10);

    				//right 7
    				g.drawLine(maxWidth + 3, maxHeight - 13, maxWidth + 8, maxHeight - 13);
    				g.drawLine(maxWidth + 8, maxHeight - 13, maxWidth + 5, maxHeight - 3);
    				g.drawLine(maxWidth + 3, maxHeight - 13, maxWidth + 3, maxHeight - 10);
    			}
    			else if (getDegreeAngle(currHRLeft) < 0)
    			{
    				int numHeight;
    				yCoor = SundialCompute.calculateOpp(getDegreeAngle(currHRLeft + 1), width);
    				numHeight = (int) Math.round(height - yCoor) + minHeight;

    				//left 8
    				g.drawLine(minWidth - 8, numHeight - 7, minWidth - 3, numHeight - 7);
    				g.drawLine(minWidth - 8, numHeight - 7, minWidth - 8, numHeight + 3);
    				g.drawLine(minWidth - 8, numHeight + 3, minWidth - 3, numHeight + 3);
    				g.drawLine(minWidth - 3, numHeight + 3, minWidth - 3, numHeight - 7);
    				g.drawLine(minWidth - 8, numHeight - 2, minWidth - 3, numHeight - 2);

    				//right 8
    				g.drawLine(maxWidth + 3, numHeight - 7, maxWidth + 8, numHeight - 7);
    				g.drawLine(maxWidth + 3, numHeight - 7, maxWidth + 3, numHeight + 3);
    				g.drawLine(maxWidth + 3, numHeight + 3, maxWidth + 8, numHeight + 3);
    				g.drawLine(maxWidth + 8, numHeight + 3, minWidth + 8, numHeight - 7);
    				g.drawLine(maxWidth + 3, numHeight - 2, minWidth + 8, numHeight - 2);
    			}
    			else
    			{
    				int numHeight;
    				yCoor = SundialCompute.calculateOpp(getDegreeAngle(currHRLeft), width);

    				numHeight = (int) Math.round(height - yCoor) + minHeight;

    				//left 7
    				g.drawLine(minWidth - 8, numHeight - 7, minWidth - 3, numHeight - 7);
    				g.drawLine(minWidth - 3, numHeight - 7, minWidth - 6, numHeight + 3);
    				g.drawLine(minWidth - 8, numHeight - 7, minWidth - 8, numHeight - 4);

    				//right 7
    				g.drawLine(maxWidth + 3, numHeight - 7, maxWidth + 8, numHeight - 7);
    				g.drawLine(maxWidth + 8, numHeight - 7, maxWidth + 5, numHeight + 3);
    				g.drawLine(maxWidth + 3, numHeight - 7, maxWidth + 3, numHeight - 4);
    			}
    		}
    		else
    		{
    			currHRLeft = 6;

    			if (Math.round(getDegreeAngle(currHRLeft)) == 0)
    			{
    				//left 6
    				g.drawLine(minWidth - 8, maxHeight - 3, minWidth - 8, maxHeight - 13);
    				g.drawLine(minWidth - 8, maxHeight - 13, minWidth - 3, maxHeight - 13);
    				g.drawLine(minWidth - 8, maxHeight - 8, minWidth - 3, maxHeight - 8);
    				g.drawLine(minWidth - 3, maxHeight - 8, minWidth - 3, maxHeight - 3);
    				g.drawLine(minWidth - 8, maxHeight - 3, minWidth - 3, maxHeight - 3);

    				//right 6
    				g.drawLine(maxWidth + 3, maxHeight - 3, maxWidth + 3, maxHeight - 13);
    				g.drawLine(maxWidth + 3, maxHeight - 13, maxWidth + 8, maxHeight - 13);
    				g.drawLine(maxWidth + 3, maxHeight - 8, maxWidth + 8, maxHeight - 8);
    				g.drawLine(maxWidth + 8, maxHeight - 8, maxWidth + 8, maxHeight - 3);
    				g.drawLine(maxWidth + 3, maxHeight - 3, maxWidth + 8, maxHeight - 3);
    			}

    			else if (getDegreeAngle(currHRLeft) < 0)
    			{
    				int numHeight;
    				yCoor = SundialCompute.calculateOpp(getDegreeAngle(currHRLeft + 1), width);
    				numHeight = (int) Math.round(height - yCoor) + minHeight;

    				//left 7
    				g.drawLine(minWidth - 8, numHeight - 13, minWidth - 3, numHeight - 13);
    				g.drawLine(minWidth - 3, numHeight - 13, minWidth - 6, numHeight - 3);
    				g.drawLine(minWidth - 8, numHeight - 13, minWidth - 8, numHeight - 10);

    				//right 7
    				g.drawLine(maxWidth + 3, numHeight - 13, maxWidth + 8, numHeight - 13);
    				g.drawLine(maxWidth + 8, numHeight - 13, maxWidth + 5, numHeight - 3);
    				g.drawLine(maxWidth + 3, numHeight - 13, maxWidth + 3, numHeight - 10);
    			}
    			else
    			{
    				int numHeight;

    				yCoor = SundialCompute.calculateOpp(getDegreeAngle(currHRLeft), width);

    				numHeight = (int) Math.round(height - yCoor) + minHeight;

    				//left 6
    				g.drawLine(minWidth - 8, numHeight + 3, minWidth - 8, numHeight - 7);
    				g.drawLine(minWidth - 8, numHeight - 7, minWidth - 3, numHeight - 7);
    				g.drawLine(minWidth - 8, numHeight - 2, minWidth - 3, numHeight - 2);
    				g.drawLine(minWidth - 3, numHeight - 2, minWidth - 3, numHeight + 3);
    				g.drawLine(minWidth - 8, numHeight + 3, minWidth - 3, numHeight + 3);

    				//right 6
    				g.drawLine(maxWidth + 3, numHeight + 3, maxWidth + 3, numHeight - 7);
    				g.drawLine(maxWidth + 3, numHeight - 7, maxWidth + 8, numHeight - 7);
    				g.drawLine(maxWidth + 3, numHeight - 2, maxWidth + 8, numHeight - 2);
    				g.drawLine(maxWidth + 8, numHeight - 2, maxWidth + 8, numHeight + 3);
    				g.drawLine(maxWidth + 3, numHeight + 3, maxWidth + 8, numHeight + 3);
    			}
    		}

    		//draw line and labels time in boarder

    		for (hrLineCounter = 0; hrLineCounter < 6; hrLineCounter++)
    		{

    			drawDegree = getDegreeAngle(currHRLeft);
    			yCoor = SundialCompute.calculateOpp(drawDegree, width);

    			if (yCoor > height)
    			{
    				yCoor -= height;
    				xCoor = SundialCompute.calculateAdj(drawDegree, yCoor);

    				coordinateLeft[0] = minWidth + (int) Math.round(xCoor);
    				coordinateLeft[1] = minHeight;


    				coordinateRight[0] = maxWidth - (int) Math.round(xCoor);
    				coordinateRight[1] = minHeight;

    			}

    			else
    			{
    				coordinateLeft[0] = minWidth;
    				coordinateLeft[1] = (int) Math.round(height - yCoor) + minHeight;


    				coordinateRight[0] = maxWidth;
    				coordinateRight[1] = (int) Math.round(height - yCoor) + minHeight;
    			}

    			//drawing line

    			//do NOT draw line if outside of sundial box maxHeight range
    			if (!((coordinateLeft[1] > 500) || (coordinateRight[1] > 500)))
    			{
    				g.drawLine(centerX,maxHeight,coordinateLeft[0],coordinateLeft[1]);
    				g.drawLine(centerX,maxHeight,coordinateRight[0],coordinateRight[1]);
    			}

    			currHRLeft++;
    		}

    		//12 or 1 o'clock position
    		if (DLS)
    		{
    			//currRight
    			g.drawLine(centerX,maxHeight,centerX,minHeight);

    			//drawing label: 1
    			g.drawLine(centerX,minHeight - 15,centerX,(minHeight - borderSp) + 15);
    		}
    		else
    		{
    			//currLeft
    			g.drawLine(centerX,maxHeight,centerX,minHeight);

    			//drawing label: 12
    			g.drawLine(centerX - 2, minHeight - 15, centerX - 2, (minHeight - borderSp) + 15);

    			g.drawLine(centerX + 2, (minHeight - borderSp) + 15, centerX + 5, (minHeight - borderSp) + 15);
    			g.drawLine(centerX + 5, (minHeight - borderSp) + 15, centerX + 5, (minHeight - borderSp) + 45);
    			g.drawLine(centerX + 5, (minHeight - borderSp) + 45, centerX + 2, (minHeight - borderSp) + 45);
    			g.drawLine(centerX + 2, (minHeight - borderSp) + 45, centerX + 2, (minHeight - borderSp) + 75);
    			g.drawLine(centerX + 2, (minHeight - borderSp) + 75, centerX + 5, (minHeight - borderSp) + 75);
    		}

    	}
    }
    
    /////////////////////////////////////////////////////////////////////
    public boolean daylightsavings()
    {
    	
    	boolean DLS;
    	
    	DLS = calculations.getDLS();
    	
    	return DLS;
    }
    
    public double getDegreeAngle(int currHRLeft)
    {	
    	//Nov 27 - wasteful work, but least editing
    	Double[] degree = new Double[6];
    	Double[] unconvertedAngles = calculations.hourAngles();

    	for (int i=0; i<6; i++) {
    		if (i==0){
    			degree[i] = unconvertedAngles[i];
    		} else {
    			degree[i] = 90 - unconvertedAngles[i];
    		}
    	}
    	
    	if (!(daylightsavings()))
    	{
    		return Math.abs(degree[currHRLeft - 6].doubleValue());
    	}
    	else
    	{
    		return Math.abs(degree[currHRLeft - 7].doubleValue());
    	}
    }
    
    public double getLatitude()
    {    	
    	return calculations.getLatitude();
    }
    /////////////////////////////////////////////////////////////////////

    
    
}